/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * Copyright (C) 2001 Gerwin Klein <lsf@jflex.de>                          *
 * All rights reserved.                                                    *
 *                                                                         *
 * This is a modified version of the example from                          *
 *   http://www.lincom-asg.com/~rjamison/byacc/                            *
 *                                                                         *
 * Thanks to Larry Bell and Bob Jamison for suggestions and comments.      *
 *                                                                         *
 * This program is free software; you can redistribute it and/or modify    *
 * it under the terms of the GNU General Public License. See the file      *
 * COPYRIGHT for more information.                                         *
 *                                                                         *
 * This program is distributed in the hope that it will be useful,         *
 * but WITHOUT ANY WARRANTY; without even the implied warranty of          *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
 * GNU General Public License for more details.                            *
 *                                                                         *
 * You should have received a copy of the GNU General Public License along *
 * with this program; if not, write to the Free Software Foundation, Inc., *
 * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                 *
 *                                                                         *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

%{
    import java.io.*;
    import java.util.List;
    import java.util.ArrayList;
    import java.util.Set;
    import java.util.HashSet;
%}

// Symbols.

%token <sval> IDENTIFIER
%token <sval> STRING
%token BEGINTAG
%token ENDTAG

%type <parameterlistval> Parameters
%type <parameterlistval> Parameter
%type <sval> Function
%type <sval> TagIdentifier

%%

File:
    //| Parameters {System.out.println($1);}
    | error
    | Tag
    | Function
    | File Tag
    | File error
    | File Function
    ;

TagIdentifier:
    IDENTIFIER {$$=$1;}
    | IDENTIFIER ':' IDENTIFIER {$$=$1+":"+$3;}
    ;

Tag:    BEGINTAG TagIdentifier Parameters ENDTAG {
            //System.out.println("Tag: " + $2.toString());
            //System.out.println("   Params: " + $3);

            if($2.equals("g:submitButton")){
                int a = 1;
            }

            ParameterList params = $3;
            if($2.equals("g:message")){
                I18nProperty property = params.getI18nProperty();
                if (property != null){
                    i18nProperties.add(property);
                }
            } else {
                i18nProperties.addAll(params.getI18nProperties());
            }
          }
        ;

Function: IDENTIFIER '(' Parameters ')' {
            ParameterList params = $3;
            String result = $1.toString() + "(" + $3 + ")";
            //System.out.println("Function: " + result);
            if($1.equals("message") || $1.equals("g.message")){
                I18nProperty property = params.getI18nProperty();
                if (property != null){
                    i18nProperties.add(property);
                } 
                $$=result;
            } else {
                i18nProperties.addAll(params.getI18nProperties());
            }
        }

Parameters:
        /* empty */ {$$=new ParameterList();}
        | Parameter {
                ParameterList params = new ParameterList();
                params.addAll($1);
                $$=params;
            }
        | IDENTIFIER {
                ParameterList params = new ParameterList();
                params.add(new Parameter($1,"",$1));
                $$=params;
            }
        | Parameters ',' Parameter {
                $1.addAll($3);
                $$=$1;
            }
        | Parameters Parameter {
                $1.addAll($2);
                $$=$1;
            }
        | Parameters "'" IDENTIFIER {
                $1.add(new Parameter($3,"",$3));
                $$=$1;
            }
        | Parameters IDENTIFIER {
                $1.add(new Parameter($2,"",$2));
                $$=$1;
            }
        ;

Parameter:
        IDENTIFIER ':' STRING {
                ParameterList params = new ParameterList();
                params.add(new Parameter($1, $3, $1+":"+$3));
                $$=params;
            }
        | IDENTIFIER '=' STRING {
                ParameterList params = new ParameterList();
                params.add(new Parameter($1, $3, $1+"="+$3));
                $$=params;
            }
        | Function {
                ParameterList params = new ParameterList();
                params.add(new Parameter("", $1, $1));
                $$=params;
            }
        | IDENTIFIER ':' '[' Parameters ']' {
            ParameterList params = new ParameterList();
            params.add(new Parameter($1, $4, $1+":["+$4+"]"));
            $$=params;
          }
        | IDENTIFIER '=' '[' Parameters ']' {
            ParameterList params = new ParameterList();
            params.add(new Parameter($1, $4, $1+":["+$4+"]"));
            $$=params;
          }
        ;


%%
  private Yylex lexer;
  private Set<I18nProperty> i18nProperties = new HashSet<I18nProperty>();

  private int yylex () {
    int yyl_return = -1;
    try {
      yylval = new I18nParserVal(0);
      yyl_return = lexer.yylex();
    }
    catch (IOException e) {
      System.err.println("IO error :"+e);
    }
    return yyl_return;
  }


  public void yyerror (String error) {
    //ignoring errors, otherwise we had to recognize whole groovy, java, etc. grammars
    //System.err.println ("Bison Error: " + error);
  }


  public Parser(Reader r) {
    lexer = new Yylex(r, this);
  }

    public Set<I18nProperty> getI18nProperties(){
        yyparse();
        return i18nProperties;
    }
